<?php

namespace Admin\Controller;

use Org\Util\Collect;
use Org\Util\Numeric;
use Org\Util\String;
use Org\Util\DateTime;
use Think\Controller;

class DaController extends Controller
{
    /**
     * 后台配置项设置
     */
    public function config()
    {
        // 后台是否已登录验证
        $user = D('User');
        if (!$user->is_admin_login()) {
            exit('<script type="text/javascript">top.location="' . RU('/login/login') . '";</script>');
        }

        if (IS_GET) {
            $show = $this->data();
            $this->assign(compact('show'));
            $this->display();
        } else {
            $input = I('post.');
            $ret   = $this->data($input);
            if ($ret) {
                $this->success('保存完成');
            } else {
                $this->error('保存失败');
            }
        }
    }

    /**
     * Api 保存采集数据
     * 保存失败输出error,成功输出success
     */
    public function save()
    {
        /*
         * 采集模块没有开启
         * 问题名称或者分类不能为空
         * 无效的问题发布日期
         * 问题添加出错
         * --------------------
         * 问题发布成功
         */
        $config = $this->data();

        if ($config['is_enable'] === 0) {
            exit('采集模块没有开启');
        }

        $post = I('post.');  // cat_id title content reply best time
        if (empty($post['title']) || empty($post['cat_id'])) {
            exit('问题名称或者分类不能为空');
        }

        $user_count = $this->count_need_uid($post);
        $user_list  = $this->get_config_users($config['users']);  // 来源于管理员指定用户
        $user_list  = $this->make_user_ids($user_count, $user_list);
        shuffle($user_list);

        $type = $config['time_type'];  // origin-原始时间 day-一天内随机 week-一周内随机 month-一月内随机
        /*
         * 时间不能指定为当前时间，必须是过去的一个时间点，或者过去时间的一个范围
         * 如果问题的发布时间设置为当前时间，则其回复会发生在未来的时间点，不符合业务逻辑
         */
        if ($type === 'origin') { // 指定时间
            $addtime = DateTime::isValidate($post['time']);
            if ($addtime === false) {  // 无效的日期时间格式
//                exit('无效的问题发布日期');  // 容错处理
                $addtime = DateTime::getRandTimeByType('day');
            }
        } else {  // 随机范围时间
            $addtime = DateTime::getRandTimeByType($type);
        }

        $data_question = array(
            'category1'   => $post['cat_id'],
            'title'       => $post['title'],
            'describe'    => $post['content'],
            'reward_open' => '0',
            'addtime'     => $addtime,
        );

        $data_question['click'] = rand($config['click_min'], $config['click_max']);

        $ret_question = D('Question')->question_add(array_pop($user_list), $data_question);

        if ($ret_question['status'] === false) {
            exit('问题添加出错');
        }

        if (!empty($post['best'])) {
            $post['reply'] = Collect::randInsert($post['reply'], array('best' => $post['best']));
        }

        if (!empty($post['reply'])) {
            // 计算间隔时间
            $jgtime['max'] = (time() - $addtime) / count($post['reply']);
            $_time         = ceil($jgtime['max'] / 10);
            $min_time      = 60 * 10;  // 回复的时间间隔范围(秒)
            $jgtime['min'] = ($_time > $min_time) ? $min_time : $_time;
            // 回复处理
            foreach ($post['reply'] as $key => $content) {
                $data_reply['content'] = $content;
                $addtime               += rand($jgtime['min'], $jgtime['max']);
                $data_reply['addtime'] = $addtime;
                $_uid                  = array_pop($user_list);
                $ret_reply = D('Answer')->answer_add($_uid, $ret_question['qid'], $data_reply);
                if ($key === 'best' && $ret_reply['status']) {
                    $aid = $ret_reply['aid'];
                    D('Answer')->answer_adoption($_uid, $ret_question['qid'], $aid);
                }
            }
        }
        exit('问题发布成功');
    }

    /**
     * Api 获取分类
     */
    public function cat()
    {
        // fixme 目前仅支持一级分类
        $cat_list = D('Category')->get_list(1);

        echo '<select>' . PHP_EOL;
        foreach ($cat_list as $item) {
            echo '<option value="' . $item['c_id'] . '">' . $item['c_title'] . '</option>' . PHP_EOL;
        }
        echo '</select>';
    }

    /**
     * 统计所需参与用户数
     * 参数$post为引用传值，会将其reply字段转换为数组，并对best字段作过滤处理
     * @param array $post
     * @return int
     */
    private function count_need_uid(&$post)
    {
        $count_uid = 1;

        $content = trim($post['reply']);
        $_list   = array();
        if (!empty($content)) {
            $_list     = explode("###", $content);
            $_list     = array_filter($_list, function ($item) {
                $item = trim($item);
                return (!empty($item) && strlen($item) <= 1000);
            });
            $_list     = array_values($_list);
            $count_uid += count($_list);
        }

        $_best = trim($post['best']);
        if (!empty($_best) && strlen($_best) <= 1000) {
            $count_uid += 1;
        } else {
            $_best = '';
        }

        $post['best']  = $_best;
        $post['reply'] = $_list;

        return $count_uid;
    }

    /**
     * 生成用户id列表
     *
     * @param       $user_count
     * @param array $user_list
     * @return array|mixed
     */
    private function make_user_ids($user_count, $user_list = array())
    {
        $diff = count($user_list) - $user_count;
        if ($diff < 0) {
            $diff     = abs($diff);
            $user_arr = array();
            while ($diff) {
                $username = strtolower(String::randString(rand(6, 8)));
                $ret      = D('User')->user_reg($username, '', '', '123456');  // 指定密码
                if ($ret['status'] == 1) {
                    D('User')->where(array('username' => $username))->setField('entrance', 0);
                    $user_arr[] = $username;
                    $diff--;
                }
            }
            $user_list = array_merge($user_list, $user_arr);
        }
        $user_list = D('User')->where(array('username' => array('in', $user_list)))->getField('uid', true);
        return $user_list;
    }

    /**
     * 获取自定义用户名列表
     * @param string $users
     * @return array
     */
    private function get_config_users($users)
    {
        $user_list = array();
        if (!empty($users)) {
            $user_list = explode(',', $users);
            // 过滤不存在的用户
            $map       = array('username' => array('in', $user_list));
            $user_list = D('User')->where($map)->getField('username', true) ?: array();
        }
        return $user_list;
    }

    /**
     * 获取/设置采集配置项
     * @param mixed $data
     * @return bool|mixed
     */
    private function data($data = null)
    {
        $filename     = 'storage/admin/da/config';
        $storage_path = realpath(APP_PATH . '../data') . '/';
        if (!isset($data)) {
            $config              = F($filename, '', $storage_path);
            $config['is_enable'] = isset($config['is_enable']) ? $config['is_enable'] : 0;
            $config['users']     = isset($config['users']) ? $config['users'] : '';
            $config['click_min'] = isset($config['click_min']) ? $config['click_min'] : 1;
            $config['click_max'] = isset($config['click_max']) ? $config['click_max'] : 1;
            $config['time_type'] = isset($config['time_type']) ? $config['time_type'] : 'origin';
            return $config;
        } else {
            if (in_array($data['is_enable'], array('0', '1'))) {
                $data['is_enable'] = intval($data['is_enable']);
            } else {
                return false;
            }
            if (!in_array($data['time_type'], array('origin', 'day', 'week', 'month'))) {
                return false;
            }
            $data['click_min'] = Numeric::parseInt($data['click_min']);
            $data['click_max'] = Numeric::parseInt($data['click_max']);
            if (!($data['click_min'] !== false && $data['click_max'] !== false && $data['click_min'] > 0 && $data['click_max'] >= $data['click_min'])) {
                return false;
            }
            $data['users'] = trim($data['users']);
            F($filename, $data, $storage_path);
            return true;
        }
    }
}